import { ComponentSchema } from '../schema/schema';
import { ElementPropertyConfig } from '@farris/ide-property-panel';
import { ComponentProp } from '../property/property-config';
import FdContainerBaseComponent from '../../common/containerBase/containerBase';
import { RowNode } from '@farris/ui-treetable';
import { ComponentContextMenuManager } from '../context-menu/context-menu.manager';
import { BuilderHTMLElement } from '@farris/designer-element';
import { DgControl } from '../../../../utils/dg-control';
import { DesignerEnvType, DesignViewModelService, DomService, FormComponentType, RefreshFormService } from '@farris/designer-services';
import { ComponentDragDropManager } from '../drag-drop/dragAndDrapManager';
import { NoComponentProp } from '../property/nocode-property-config';
import { ComponentFactoryResolver, Injector } from '@angular/core';
import { BsModalService } from '@farris/ui-modal';
import { SaveAsTemplateEditorComponent } from '@farris/designer-devkit';
import { cloneDeep } from 'lodash-es';


export default class FdComponentComponent extends FdContainerBaseComponent {

    /** 判断当前组件是否固定上下文，这种组件不支持移动、不支持删除 */
    private isInFixedContextRules: boolean;

    private dragManager: ComponentDragDropManager;

    /** 记录列表类组件的直接父级元素schema，用于删除组件时连带删除父级的新增、删除按钮 */
    private parentComponentSchemaForDataGrid: any;

    constructor(component: any, options: any) {
        super(component, options);
        this.dragManager = new ComponentDragDropManager(this);
        this.isInFixedContextRules = this.dragManager.checkIsInFixedContextRules();

        this.parentComponentSchemaForDataGrid = this.getParentComponentSchemaForDataGrid();
    }


    getDefaultSchema(): any {
        return ComponentSchema;
    }

    init(): any {
        this.componentId = this.component.id;
        this.viewModelId = this.component.viewModel;

        this.getCustomToolbarConfig();

        super.init();
    }

    getTemplateName(): string {
        return 'Component';
    }

    getStyles(): string {
        return ' display: inherit;flex-direction: inherit;margin-bottom:10px';
    }


    /**
     * 组装属性面板配置数据
     */
    getPropertyConfig(): ElementPropertyConfig[] {
        const serviceHost = this.options.designerHost;

        if (this.envType === DesignerEnvType.noCode) {
            const prop: NoComponentProp = new NoComponentProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        } else {
            const prop: ComponentProp = new ComponentProp(serviceHost, this.viewModelId, this.componentId);
            const propertyConfig: ElementPropertyConfig[] = prop.getPropConfig(this.component);
            return propertyConfig;
        }
    }

    /**
     * 组装右键菜单
     * @param rowNode 组件在控件树上对应的行数据
     */
    resolveContextMenuConfig(rowNode: RowNode) {
        const menuManager = new ComponentContextMenuManager(this, rowNode);
        return menuManager.setContextMenuConfig();
    }

    /**
     * 判断是否可以接收拖拽新增的子级控件
     */
    canAccepts(el: BuilderHTMLElement) {
        return false;
    }
    /**
     * 是否可移位
     */
    checkCanMoveComponent(): boolean {
        return !this.isInFixedContextRules;
    }
    /**
     * 是否可删除
     */
    checkCanDeleteComponent(): boolean {
        return !this.isInFixedContextRules;
    }
    /**
     * 删除组件，用于移除视图模型和组件节点。组件引用节点已经在webform-builder中移除
     */
    onRemoveComponent(): void {
        this.removeAddDeleteBtnOnParentContainer();

        super.onRemoveComponent();
        const serviceHost = this.options.designerHost;
        const dgViewModelService = serviceHost.getService('DesignViewModelService') as DesignViewModelService;
        const domService = serviceHost.getService('DomService') as DomService;


        dgViewModelService.deleteViewModelById(this.viewModelId);
        domService.deleteComponent(this.component.id);

    }

    /**
     * 获取组件展示名称
     */
    getControlShowName() {
        const componentType = this.component.componentType;

        switch (componentType) {
            case FormComponentType.Frame: {
                return '根组件';
            }
            case FormComponentType.dataGrid: case FormComponentType.table: {
                return this.checkDataGridComponentName();
            }
            case FormComponentType.attachmentPanel: case 'AttachmentPanel': {
                return '附件组件';
            }
            case FormComponentType.listView: {
                return '列表视图组件';
            }
            case FormComponentType.modalFrame: {
                return '弹窗页面';
            }
            default: {
                if (componentType.startsWith('form')) {
                    return '卡片组件';
                }
            }
        }

        return this.component.id + '组件';
    }

    private checkDataGridComponentName() {
        const domService = this.options.designerHost.getService('DomService') as DomService;
        const treeGrid = domService.selectNode(this.component, (item) => item.type === DgControl.TreeGrid.type);
        if (treeGrid) {
            return '树表格组件';
        }
        return '表格组件';
    }

    getDragScopeElement(): HTMLElement {
        const domService = this.options.designerHost.getService('DomService') as DomService;

        // 判断是否为弹窗内部的组件，若是，则限定控件的拖拽不能超出弹出区域
        const rootCmps = domService.module.components.filter(c => c.componentType === FormComponentType.modalFrame);
        if (!rootCmps || rootCmps.length === 0) {
            return;
        }

        let rootCmpId;
        for (const cmp of rootCmps) {
            const cmpRefNode = domService.selectNode(cmp, n => n.type === DgControl.ComponentRef.type && n.component === this.component.id);
            if (cmpRefNode) {
                rootCmpId = cmp.id;
                break;
            }
        }
        if (rootCmpId) {
            const rootContainer = document.getElementById(rootCmpId);
            return rootContainer;
        }
    }

    /**
     * 删除DataGrid/Form类组件时，将父级Section或者TabPage上的相关按钮一起删除
     */
    private removeAddDeleteBtnOnParentContainer() {

        if (this.component.componentType !== 'dataGrid' && !this.component.componentType.includes('form-')) {
            return;
        }
        // 判断父级容器
        const parentComponentSchema = this.parentComponentSchemaForDataGrid;
        if (!parentComponentSchema) {
            return;
        }
        if (parentComponentSchema.toolbar && parentComponentSchema.toolbar.contents && parentComponentSchema.toolbar.contents.length) {
            parentComponentSchema.toolbar.contents.forEach(button => {
                const clickEvent = button.click;
                // 判断三段式结构
                const clickEventPath = clickEvent && clickEvent.split('.');
                if (!clickEventPath || clickEventPath.length < 3) {
                    return;
                }
                const targetViewModelId = clickEventPath[clickEventPath.length - 2];

                // 按钮绑定的命令若是在当前viewModel下，则将按钮标记为待删除
                if (targetViewModelId === this.viewModelId) {
                    button.needRemove = true;
                }
            });
            parentComponentSchema.toolbar.contents = parentComponentSchema.toolbar.contents.filter(button => !button.needRemove);

        }

    }
    /**
     * 记录列表类组件的直接父级元素schema，用于删除组件时连带删除父级的新增、删除按钮
     */
    private getParentComponentSchemaForDataGrid() {
        if (this.component.componentType !== 'dataGrid' && !this.component.componentType.includes('form-')) {
            return;
        }

        const domService = this.options.designerHost.getService('DomService') as DomService;
        const dataGrid = domService.selectNode(this.component, item => [DgControl.DataGrid.type, DgControl.Form.type].includes(item.type));
        if (!dataGrid) {
            return;
        }
        const componentRefInstance = this.parent;
        if (!componentRefInstance || componentRefInstance.type !== DgControl.ComponentRef.type) {
            return;
        }
        // 判断父级容器
        if (!componentRefInstance.parent) {
            return;
        }
        switch (componentRefInstance.parent.type) {
            case DgControl.Section.type: {
                // 父级为分组面板
                return componentRefInstance.parent.component;
            }
            case DgControl.Tab.type: {
                // 父级为标签页，需要定位到列表所在标签页项
                const targetTabPage = componentRefInstance.parent.component.contents.find(tabPage => {
                    const ref = domService.selectNode(tabPage, item => item.id === componentRefInstance.id);
                    if (ref) {
                        return true;
                    }
                });

                return targetTabPage;

            }
        }
    }



    private getCustomToolbarConfig() {
        this.customToolbarConfigs = [];

        // 零代码支持Form类组件、table类组件另存为模板
        if (this.envType == DesignerEnvType.noCode) {
            const canSaveAs = this.checkCanSaveAsTemplate();
            if (canSaveAs) {
                this.customToolbarConfigs.push(
                    {
                        id: 'saveAsTemplate',
                        title: '另存为模板',
                        icon: 'f-icon f-icon-save',
                        click: (e) => {
                            e.stopPropagation();
                            this.showSaveAsTemplateModal();
                        }
                    });
            }
        }

    }

    private checkCanSaveAsTemplate() {
        // 没有子级控件，不支持另存为
        if (!this.component.contents || !this.component.contents.length) {
            return false;
        }
        const domService = this.options.designerHost.getService('DomService') as DomService;

        const componentType = this.component.componentType;
        if (!componentType) {
            return false;
        }
        // 只支持form、table的另存为
        if (componentType !== FormComponentType.table && !componentType.includes(FormComponentType.form)) {
            return false;
        }

        // 只支持绑定主表
        const viewModel = domService.getViewModelById(this.viewModelId);
        if (!viewModel || viewModel.bindTo !== '/') {
            return false;
        }



        // 若Form中有未绑定字段的控件，不支持另存为模板
        switch (componentType) {
            case FormComponentType.table: {

                // 只支持简单类表格
                const table = domService.selectNode(this.component, item => item.type === DgControl.Table.type);
                if (!table || table.devMode !== 'simple') {
                    return false;
                }
            }
            default: {
                if (componentType.includes(FormComponentType.form)) {

                    // 若包含小分组，不支持另存为
                    const hasFieldSet = domService.selectNode(this.component, item => item.type === DgControl.FieldSet.type);
                    if (hasFieldSet) {
                        return false;
                    }


                    // 校验Form内是否有未绑定字段的控件
                    const formNode = domService.selectNode(this.component, item => item.type === DgControl.Form.type);
                    if (formNode) {
                        for (const item of formNode.contents) {
                            if (!item || !item.binding) {
                                return false;
                            }
                        }
                    }

                }
            }
        }
        return true;

    }
    /**
     * 弹出另存为模板的窗口
     */
    private showSaveAsTemplateModal() {
        // 动态创建相关的服务需要从designerHost中获取
        const serviceHost = this.options.designerHost;
        const domService = this.options.designerHost.getService('DomService') as DomService;
        const resolver = serviceHost.getService('ComponentFactoryResolver') as ComponentFactoryResolver;
        const injector = serviceHost.getService('Injector') as Injector;
        const modalService = serviceHost.getService('ModalService') as BsModalService;

        const compFactory = resolver.resolveComponentFactory(SaveAsTemplateEditorComponent);
        const compRef = compFactory.create(injector);
        const modalConfig = compRef.instance.modalConfig as any;
        modalConfig.buttons = compRef.instance.modalFooter;

        const saveAsComponentDom = cloneDeep(this.component);

        const viewModel = domService.getViewModelById(this.viewModelId);
        const componentType = this.component.componentType;

        let templateIconType;
        let templateName;
        if (componentType === 'table') {
            templateIconType = 'Table';
            templateName = '表格'
            modalConfig.height = 200;
            modalConfig.width = 450;
        } else if (componentType && componentType.includes('form-')) {
            templateIconType = 'Form';
            const sectionNode = domService.selectNode(this.component, item => item.type === DgControl.Section.type);
            templateName = sectionNode && sectionNode.mainTitle ? sectionNode.mainTitle : viewModel.name;
        }

        compRef.instance.editorParams = {
            controlCategory: 'container',
            controlTitle: templateName + '模板',
            controlDom: saveAsComponentDom,
            viewModelId: this.viewModelId,
            templateIconType: templateIconType

        }

        const modalPanel = modalService.show(compRef, modalConfig);
        compRef.instance.closeModal.subscribe(() => {
            modalPanel.close();
        });
        compRef.instance.submitModal.subscribe(() => {
            modalPanel.close();

            // 刷新工具箱
            const refreshFormService = this.options.designerHost.getService('RefreshFormService') as RefreshFormService;
            if (refreshFormService && refreshFormService.refreshControlBox) {
                refreshFormService.refreshControlBox.next();
            }
        });

    }
}
